#include<iostream>
#include<unistd.h>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<cstring>
#include<string>

using namespace std;
// ./tcpclient server-ip server-port
int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        std::cerr << "Usage: " << argv[0] << " server-ip server-port" << std::endl;
        exit(0);
    }
    string serverip = argv[1];
    uint16_t serverport = stoi(argv[2]);

    int sockfd = socket(AF_INET,SOCK_STREAM,0);//创建套接字
    if(sockfd<0)
    {
        cerr<<"create sockfd error"<<endl;
        exit(1);
    }

    //2.不需要显示的bind，但是一定要有自己的IP和port，所以需要隐式的bind，OS会自动bind sockfd，用自己的IP和随机端口号
    // 什么时候进行自动bind？If the connection or binding succeeds 连接成功之后绑定
    struct sockaddr_in server;
    memset(&server,0,sizeof(server));//进行清空
    server.sin_family = AF_INET;
    server.sin_port = htons(serverport);
    server.sin_addr.s_addr = inet_addr(serverip.c_str());

    int n = connect(sockfd,(struct sockaddr*)&server,sizeof(server));//建立连接
    if (n < 0)
    {
        std::cerr << "connect socket error" << std::endl;
        exit(2);
    }
    while(true)
    {
        string line;
        cout<<"Enter#";
        getline(cin,line);

        write(sockfd,line.c_str(),line.size());//发送消息

        char echo_buffer[1024];
        n = read(sockfd,echo_buffer,sizeof(echo_buffer));//收到消息
        if(n>0)
        {
            echo_buffer[n] = 0;
            std::cout << echo_buffer << std::endl;
        }
        else
        {
            break;
        }
    }
    close(sockfd);
    return 0;
}